/*
* JBoss, Home of Professional Open Source
* Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
*/
package org.searchisko.api.testtools;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.io.IOUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import org.json.JSONException;
import org.junit.Assert;
import org.mockito.Mockito;
import org.searchisko.api.util.SearchUtils;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
/**
* Helper methods for Unit tests.
*
* @author Vlastimil Elias (velias at redhat dot com)
*/
public abstract class TestUtils {
/**
* Assert date is current timestamp.
*
* @param actualDate to assert
* @see #assertCurrentDate(long)
*/
public static void assertCurrentDate(Date actualDate) {
Assert.assertNotNull(actualDate);
assertCurrentDate(actualDate.getTime());
}
/**
* Assert current timestamp. There is 1000ms tolerance for future because assertion may run with some delay against
* current date creation to asserted variable.
*
* @param actualDate to assert in millis
*/
public static void assertCurrentDate(long actualDate) {
long l = System.currentTimeMillis() - actualDate;
Assert.assertTrue(l >= 0 && l <= 1000);
}
/**
* Assert list contains expected values.
*
* @param expectedValuesCommaSeparated comma separated list of expected values
* @param actualValue actual list with string values
*/
public static void assertEqualsListValue(String expectedValuesCommaSeparated, List<String> actualValue) {
Assert.assertArrayEquals(expectedValuesCommaSeparated != null ? expectedValuesCommaSeparated.split(",") : null,
actualValue != null ? actualValue.toArray(new String[] {}) : null);
}
/**
* Assert passed in object is REST {@link Response} and has given status.
*
* @param actual object to check
* @param expectedStatus to check
* @return actual object casted to {@link Response} so other assertions may be performed on it.
*/
public static Response assertResponseStatus(Object actual, Response.Status expectedStatus) {
return assertResponseStatus(actual, expectedStatus, null);
}
/**
* Assert passed in object is REST {@link Response} and has given status and string as Entity object.
*
* @param actual object to check
* @param expectedStatus to check
* @param expectedContent of response
* @return actual object casted to {@link Response} so other assertions may be performed on it.
*/
public static Response assertResponseStatus(Object actual, Response.Status expectedStatus, String expectedContent) {
if (actual == null) {
Assert.fail("Result must be response Response object, but is null");
}
if (!(actual instanceof Response))
Assert.fail("Result must be response Response object, but is " + actual.getClass().getName());
Response r = (Response) actual;
Assert.assertEquals(expectedStatus.getStatusCode(), r.getStatus());
if (expectedContent != null)
Assert.assertEquals(expectedContent, r.getEntity());
return r;
}
/**
* Assert JSON equals to written by the StreamingOutput.
*
* @param expected value
* @param actual value. Has to be instance of StreamingOutput
* @throws IOException
* @throws JSONException
*/
public static void assetJsonStreamingOutputContent(String expected, Object actual) throws IOException, JSONException {
if (!(actual instanceof StreamingOutput)) {
Assert.fail("Result must be StreamingOutput but is " + actual);
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
((StreamingOutput) actual).write(output);
JSONAssert.assertEquals(expected, output.toString(), JSONCompareMode.NON_EXTENSIBLE);
}
/**
* Assert string value equals one written by the StreamingOutput.
*
* @param expectedPattern regexp value used to match
* @param actual value
* @throws IOException
*/
public static void assetStreamingOutputContentRegexp(String expectedPattern, Object actual) throws IOException {
if (!(actual instanceof StreamingOutput)) {
Assert.fail("Result must be StreamingOutput but is " + actual);
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
((StreamingOutput) actual).write(output);
if (!output.toString().matches(expectedPattern)) {
Assert.fail("Expected regexp pattern '" + expectedPattern + "' do not match with content: " + output.toString());
}
}
/**
* Assert passed string is same as content of given file loaded from classpath.
*
* @param expectedFilePath path to file inside classpath
* @param actual content to assert
* @throws IOException
*/
public static void assertStringFromClasspathFile(String expectedFilePath, String actual) throws IOException {
Assert.assertEquals(readStringFromClasspathFile(expectedFilePath), actual);
}
/**
* Assert passed in JSON string is same as JSON content of given file loaded from classpath. JSONs are compared in
* NON_EXTENSIBLE way, this means array items do not have to be in the same order but additional fields
* (extensibility) is considered a fail.
*
* @param expectedJsonFilePath path to JSON file inside classpath
* @param actualJsonString JSON content to assert for equality
* @throws IOException
*/
public static void assertJsonContentFromClasspathFile(String expectedJsonFilePath, String actualJsonString)
throws IOException, JSONException {
JSONAssert.assertEquals(readStringFromClasspathFile(expectedJsonFilePath), actualJsonString,
JSONCompareMode.NON_EXTENSIBLE);
}
/**
* Assert passed in JSON string is same as JSON content of given file loaded from classpath.
*
* @param expectedJsonString expected JSON content to assert for equality
* @param actualJsonString JSON content to assert for equality
* @throws IOException
*/
public static void assertJsonContent(String expectedJsonString, String actualJsonString) throws IOException {
JsonNode actualRootNode = getMapper().readValue(actualJsonString, JsonNode.class);
JsonNode expectedRootNode = getMapper().readValue(expectedJsonString, JsonNode.class);
Assert.assertEquals(expectedRootNode, actualRootNode);
}
/**
* Assert passed in JSON string is same as JSON content of given file loaded from classpath.
*
* @param expectedJsonString expected JSON content to assert for equality
* @param actualJsonMap JSON content to assert for equality
* @throws IOException
*/
public static void assertJsonContent(String expectedJsonString, Map<String, Object> actualJsonMap) throws IOException {
JsonNode actualRootNode = getMapper().readValue(SearchUtils.convertJsonMapToString(actualJsonMap), JsonNode.class);
JsonNode expectedRootNode = getMapper().readValue(expectedJsonString, JsonNode.class);
Assert.assertEquals(expectedRootNode, actualRootNode);
}
/**
* Assert passed in JSON content is same as JSON content of given file loaded from classpath.
*
* @param expectedJsonMap expected JSON content to assert for equality
* @param actualJsonMap JSON content to assert for equality
* @throws IOException
*/
public static void assertJsonContent(Map<String, Object> expectedJsonMap, Map<String, Object> actualJsonMap)
throws IOException {
JsonNode actualRootNode = getMapper().readValue(SearchUtils.convertJsonMapToString(actualJsonMap), JsonNode.class);
JsonNode expectedRootNode = getMapper().readValue(SearchUtils.convertJsonMapToString(expectedJsonMap),
JsonNode.class);
Assert.assertEquals(expectedRootNode, actualRootNode);
}
private static ObjectMapper getMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
/**
* Read file from classpath into String. UTF-8 encoding expected.
*
* @param filePath in classpath to read data from.
* @return file content.
* @throws IOException
*/
public static String readStringFromClasspathFile(String filePath) throws IOException {
StringWriter stringWriter = new StringWriter();
IOUtils.copy(TestUtils.class.getResourceAsStream(filePath), stringWriter, "UTF-8");
return stringWriter.toString();
}
/**
* Read JSON file from classpath into Map of Map structure.
*
* @param filePath path inside classpath pointing to JSON file to read
* @return parsed JSON file
* @throws SettingsException
*/
public static Map<String, Object> loadJSONFromClasspathFile(String filePath) {
XContentParser parser = null;
try {
parser = XContentFactory.xContent(XContentType.JSON).createParser(TestUtils.class.getResourceAsStream(filePath));
return parser.mapOrderedAndClose();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
} finally {
if (parser != null)
parser.close();
}
}
public static UriInfo prepareUriInfiWithParams(String... params) {
UriInfo uriInfoMock = Mockito.mock(UriInfo.class);
MultivaluedMap<String, String> qp = new MultivaluedMapImpl<String, String>();
for (int i = 0; i < params.length; i = i + 2) {
qp.add(params[i], params[i + 1]);
}
Mockito.when(uriInfoMock.getQueryParameters()).thenReturn(qp);
return uriInfoMock;
}
public static ArrayList<String> createListOfStrings(String... strings) {
ArrayList<String> ret = new ArrayList<>();
if (strings != null) {
for (String s : strings) {
ret.add(s);
}
}
return ret;
}
public static Set<String> createSetOfStrings(String... strings) {
Set<String> ret = new LinkedHashSet<>();
if (strings != null) {
for (String s : strings) {
ret.add(s);
}
}
return ret;
}
}